package com.xdf.docmanagementsystem.controller;

import com.xdf.docmanagementsystem.common.base.BaseController;
import com.xdf.docmanagementsystem.common.util.Example;
import com.xdf.docmanagementsystem.common.util.ExcelUtil;
import com.xdf.docmanagementsystem.common.util.IOUtil;
import com.xdf.docmanagementsystem.common.util.ObjectUtil;
import com.xdf.docmanagementsystem.dto.ExcelModel;
import com.xdf.docmanagementsystem.entity.*;
import com.xdf.docmanagementsystem.enums.EmployeeFieldEnum;
import com.xdf.docmanagementsystem.enums.OperatorEnum;
import com.xdf.docmanagementsystem.enums.PathEnum;
import com.xdf.docmanagementsystem.enums.ResponseEnum;
import com.xdf.docmanagementsystem.service.EmergencyContactPersonService;
import com.xdf.docmanagementsystem.service.EmpExtraFileService;
import com.xdf.docmanagementsystem.service.EmployeeDailyRecordService;
import com.xdf.docmanagementsystem.vo.EmpExtraFileVo;
import com.xdf.docmanagementsystem.vo.EmployeeModelVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.xdf.docmanagementsystem.service.EmployeeService;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

/**
 * @Description : 自动生成的控制层
 * @Author : ZK
 * @Date : 2020-06-23 08:48:29
 */
@Api(tags = "员工")
@CrossOrigin
@RestController
@RequiresUser
@RequestMapping("/employee")
public class EmployeeController extends BaseController {
    private static Mapper mapper = new DozerBeanMapper();

    @Autowired
    private EmployeeService service;
    @Autowired
    private EmpExtraFileService extraFileService;
    @Autowired
    private EmergencyContactPersonService emergencyContactPersonService;
    @Autowired
    private EmployeeDailyRecordService dailyRecordService;

    /**
     * @Description : 选择新增
     * @Return : ResponseResult<Void>
     * @Author : ZK
     * @Date : 2020-06-23 08:48:29
     */
    @ApiOperation(value = "选择新增", httpMethod = "POST", notes = "自动生成的新增方法")
    @RequestMapping(value = "/insertSelective", method = RequestMethod.POST)
    public ResponseResult<Void> insertSelective(Employee record) throws Exception {
        service.insertSelective(record);
        return new ResponseResult<Void>(true, ResponseEnum.OK.getState(), ResponseEnum.OK.getMessage());
    }

    /**
     * @Description : 批量新增
     * @Return : ResponseResult<Void>
     * @Author : ZK
     * @Date : 2020-06-23 08:48:29
     */
    @ApiOperation(value = "批量新增", httpMethod = "POST", notes = "自动生成的新增方法")
    @RequestMapping(value = "/multiInsert", method = RequestMethod.POST)
    public ResponseResult<Void> multiInsert(@RequestBody List<Employee> list) throws Exception {
        service.multiInsert(list);
        return new ResponseResult<Void>(true, ResponseEnum.OK.getState(), ResponseEnum.OK.getMessage());
    }

    /**
     * @Description : 选择修改
     * @Return : Employee
     * @Author : ZK
     * @Date : 2020-06-23 08:48:29
     */
    @ApiOperation(value = "选择修改", httpMethod = "PUT", notes = "自动生成的修改方法")
    @RequestMapping(value = "/updateSelective", method = RequestMethod.POST)
    public ResponseResult<Void> updateSelective(Employee record) throws Exception {
        Assert.notNull(record, ResponseEnum.NOT_ALLOW.getMessage());
        Assert.state(record.getId() != null, ResponseEnum.NOT_ALLOW.getMessage());
        service.updateByPrimaryKeySelective(record);
        return new ResponseResult<Void>(true, ResponseEnum.OK.getState(), ResponseEnum.OK.getMessage());
    }

    /**
     * @Description : 批量修改
     * @Return : Employee
     * @Author : ZK
     * @Date : 2020-06-23 08:48:29
     */
    @ApiOperation(value = "批量修改", httpMethod = "POST", notes = "自动生成的修改方法")
    @RequestMapping(value = "/multiUpdate", method = RequestMethod.POST)
    public ResponseResult<Void> multiUpdate(@RequestBody List<Employee> list) throws Exception {
        Assert.state(list != null && list.size() > 0, ResponseEnum.NOT_ALLOW.getMessage());
        for (Employee employee : list) {
            Employee item = service.selectByPrimaryKey(employee.getId());
            Assert.notNull(item, ResponseEnum.NOT_EXIST.getMessage());
            // Assert.state(item.getDocStatus() > 1, "编号:" + item.getEmpNumber() + "已清空!");
            service.updateByPrimaryKeySelective(employee);
        }
        return new ResponseResult<Void>(true, ResponseEnum.OK.getState(), ResponseEnum.OK.getMessage());
    }

    /**
     * @Description : 根据主键查询
     * @Return : Employee
     * @Author : ZK
     * @Date : 2020-06-23 08:48:29
     */
    @ApiOperation(value = "根据主键查询", httpMethod = "GET", notes = "自动生成的查询方法")
    @RequestMapping(value = "/queryByPk/{id}", method = RequestMethod.GET)
    public EmployeeModelVo selectByPrimaryKey(@PathVariable("id") Integer id) throws Exception {
        if (id == null) return null;
        Employee employee = service.selectByPrimaryKey(id);
        List<EmergencyContactPerson> emergencyContactPeople = emergencyContactPersonService
                .selectByExample(new Example().andEq("employee_id", employee.getId()));
        EmployeeModelVo vo = mapper.map(employee, EmployeeModelVo.class);
        if (emergencyContactPeople != null && emergencyContactPeople.size() > 0) {
            vo.setPersonName(emergencyContactPeople.get(0).getPersonName());
            vo.setRelation(emergencyContactPeople.get(0).getRelation());
            vo.setTelephoneNumber(emergencyContactPeople.get(0).getTelephoneNumber());
        }
        List<EmpExtraFile> extraFiles = extraFileService.listQuery(EmpExtraFile.builder().fileStatus(1).employeeId(id).build());
        vo.setDetail(ObjectUtil.conventList(mapper, extraFiles, EmpExtraFileVo.class));
        return vo;
    }

    /**
     * @Description : 查询方法
     * @Return : java.util.List
     * @Author : ZK
     * @Date : 2020-06-23 08:48:29
     */
    @ApiOperation(value = "查询方法", httpMethod = "GET", notes = "自动生成的查询方法")
    @RequestMapping(value = "/listQuery", method = RequestMethod.GET)
    public List<Employee> query(Employee record) throws Exception {
        return service.listQuery(record);
    }

    /**
     * @Description : 根据主键删除方法
     * @Return : ResponseResult<Void>
     * @Author : ZK
     * @Date : 2020-06-23 08:48:29
     */
    @ApiOperation(value = "根据主键删除方法", httpMethod = "DELETE", notes = "自动生成的删除方法")
    @RequestMapping(value = "/deleteByPk/{id}", method = RequestMethod.POST)
    public ResponseResult<Void> deleteByPrimaryKey(@PathVariable("id") Integer id) throws Exception {
        service.deleteByPrimaryKey(id);
        return new ResponseResult<Void>(true, ResponseEnum.OK.getState(), ResponseEnum.OK.getMessage());
    }

    /**
     * 报表查询
     *
     * @param departmentId
     * @param status
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "报表查询", httpMethod = "GET", notes = "报表")
    @GetMapping("/report")
    public List<Map<String, Object>> report(
            @RequestParam(value = "departmentId", required = false) Integer departmentId,
            @RequestParam(value = "status", required = false, defaultValue = "1") Integer status) throws Exception {
        return service.report(departmentId, status);
    }

    /**
     * 文件上传
     *
     * @param fileUpload
     * @return
     * @throws Exception
     */
    @PostMapping("/upload/batch")
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<EmployeeModelVo> uploadFiles(EmployeeModelVo fileUpload) throws Exception {
        Employee emp = mapper.map(fileUpload, Employee.class);
        EmergencyContactPerson emergencyContactPerson = mapper.map(fileUpload, EmergencyContactPerson.class);
        Assert.state(service.insertSelective(emp) > 0, ResponseEnum.ERROR_ADD.getMessage());
        if (emergencyContactPerson != null) {
            emergencyContactPerson.setEmployeeId(emp.getId());
            Assert.state(emergencyContactPersonService.insertSelective(emergencyContactPerson) > 0, ResponseEnum.ERROR_ADD.getMessage());
        }

        // 日志新增
        EmployeeDailyRecord employeeDailyRecord = mapper.map(emp, EmployeeDailyRecord.class);
        if (employeeDailyRecord != null) {
            employeeDailyRecord.setModifyOperate(OperatorEnum.ADD.getOperatorName());
            dailyRecordService.insertSelective(employeeDailyRecord);
        }

        String savePath = new StringBuilder()
                .append(PathEnum.SAVE_PATH.getPath())
                .append(File.separator)
                .append(PathEnum.EMP_SUB_PATH.getPath())
                .append(File.separator)
                .append(emp.getId()).toString();
        String path = new StringBuilder()
                .append(System.getProperty("user.dir"))
                .append(File.separator)
                .append(savePath)
                .toString();

        List<MultipartFile> multipartFiles = fileUpload.getFiles();
        //  删除文件
        IOUtil.deleteFilesInDir(path);
        //  写入文件到服务器
        writeFiles(multipartFiles, path);
        return new ResponseResult<EmployeeModelVo>(true, ResponseEnum.OK.getState(), ResponseEnum.OK.getMessage(), mapper.map(emp, EmployeeModelVo.class));
    }

    /**
     * 修改
     *
     * @param vo
     * @return
     * @throws Exception
     */
    @PostMapping("upload/update")
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<EmployeeModelVo> update(EmployeeModelVo vo) throws Exception {
        Employee emp = mapper.map(vo, Employee.class);
        EmergencyContactPerson emergencyContactPerson = mapper.map(vo, EmergencyContactPerson.class);
        Assert.state(emp.getId() != null, ResponseEnum.NOT_ALLOW.getMessage());
        service.updateByPrimaryKeySelective(emp);
        // 修改联系人
        if (emergencyContactPerson != null) {
            emergencyContactPerson.setEmployeeId(emp.getId());
            List<EmergencyContactPerson> emergencyContactPeople = emergencyContactPersonService
                    .selectByExample(new Example().andEq("employee_id", emp.getId()));
            if (emergencyContactPeople != null && emergencyContactPeople.size() > 0) {
                emergencyContactPersonService.updateByExampleSelective(emergencyContactPerson,
                        new Example().andEq("employee_id", emergencyContactPeople));
            } else {
                emergencyContactPersonService.insertSelective(emergencyContactPerson);
            }
        }

        // 日志新增
        EmployeeDailyRecord employeeDailyRecord = mapper.map(emp, EmployeeDailyRecord.class);
        if (employeeDailyRecord != null) {
            employeeDailyRecord.setModifyOperate(OperatorEnum.MODIFY.getOperatorName());
            dailyRecordService.insertSelective(employeeDailyRecord);
        }

        String savePath = new StringBuilder()
                .append(PathEnum.SAVE_PATH.getPath())
                .append(File.separator)
                .append(PathEnum.EMP_SUB_PATH.getPath())
                .append(File.separator)
                .append(emp.getId()).toString();
        String path = new StringBuilder()
                .append(System.getProperty("user.dir"))
                .append(File.separator)
                .append(savePath)
                .toString();
        List<MultipartFile> multipartFiles = vo.getFiles();
        //  写入文件到服务器
        writeFiles(multipartFiles, path);
        return new ResponseResult<EmployeeModelVo>(true, ResponseEnum.OK.getState(), ResponseEnum.OK.getMessage(), mapper.map(emp, EmployeeModelVo.class));
    }

    /**
     * 根据Excel文件新增员工
     *
     * @param excel
     * @return
     */
    @PostMapping("/upload/fromExcel")
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Void> insertByExcelFiles(MultipartFile excel) throws Exception {
        Assert.notNull(excel, ResponseEnum.FAILED.getMessage());
        List<Employee> list = ExcelUtil.conventExcelFileToBean(excel.getInputStream(), excel.getOriginalFilename(), Employee.class, true, 2);
        Assert.state(list != null && list.size() > 0, ResponseEnum.NOT_ALLOW.getMessage());
        for (Employee employee : list) {
            if (employee == null || StringUtils.isEmpty(employee.getEmpName())) continue;
            service.insertSelective(employee);
            // 日志新增
            EmployeeDailyRecord employeeDailyRecord = mapper.map(employee, EmployeeDailyRecord.class);
            if (employeeDailyRecord != null) {
                employeeDailyRecord.setId(null);
                employeeDailyRecord.setModifyOperate(OperatorEnum.MODIFY.getOperatorName());
                dailyRecordService.insertSelective(employeeDailyRecord);
            }
        }
        return new ResponseResult<Void>(true, ResponseEnum.OK.getState(), ResponseEnum.OK.getMessage());
    }

    /**
     * 导出Excel人员样式模板
     *
     * @param response
     * @return
     * @throws Exception
     */
    @GetMapping("/download/template")
    public void downloadExcelTemplate(HttpServletResponse response) throws Exception {
        Map<Integer, ExcelModel> fieldMap = new HashMap<>();
        for (EmployeeFieldEnum fieldEnum : EmployeeFieldEnum.values()) {
            ExcelModel excelModel = new ExcelModel();
            excelModel.setCellValue(fieldEnum.getFieldName());
            excelModel.setComment(fieldEnum.getTitle());
            excelModel.setColIndex(fieldEnum.getSerialNo());
            fieldMap.put(fieldEnum.getSerialNo(), excelModel);
        }
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.addHeader("Content-Disposition", "attachment;filename=" + new String("Template.xlsx".getBytes(), "UTF-8"));
        ExcelUtil.createExcelTemplate(response.getOutputStream(), 0, fieldMap);
    }
}